home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / dev / misc / AmigaSDLsrc.lha / amisrc / SDL_cgxvideo.c < prev    next >
C/C++ Source or Header  |  2001-04-30  |  37KB  |  1,457 lines

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000  Sam Lantinga
  4.  
  5.     This library is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU Library General Public
  7.     License as published by the Free Software Foundation; either
  8.     version 2 of the License, or (at your option) any later version.
  9.  
  10.     This library is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.     Library General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Library General Public
  16.     License along with this library; if not, write to the Free
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.     Sam Lantinga
  20.     slouken@devolution.com
  21. */
  22.  
  23. #ifdef SAVE_RCSID
  24. static char rcsid =
  25.  "@(#) $Id: SDL_cgxvideo.c,v 1.6.2.57 2000/08/08 19:22:00 hercules Exp $";
  26. #endif
  27.  
  28. /* CGX based SDL video driver implementation.
  29. */
  30.  
  31. /*
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <unistd.h>
  35. #include <string.h>
  36. #include <sys/ioctl.h>
  37. #ifdef MTRR_SUPPORT
  38. #include <asm/mtrr.h>
  39. #include <sys/fcntl.h>
  40. #endif
  41. */
  42.  
  43. #include "SDL.h"
  44. #include "SDL_error.h"
  45. #include "SDL_timer.h"
  46. #include "SDL_thread.h"
  47. #include "SDL_video.h"
  48. #include "SDL_mouse.h"
  49. #include "SDL_endian.h"
  50. #include "SDL_sysvideo.h"
  51. #include "SDL_pixels_c.h"
  52. #include "SDL_events_c.h"
  53. #include "SDL_cgxvideo.h"
  54. #include "SDL_cgxwm_c.h"
  55. #include "SDL_amigamouse_c.h"
  56. #include "SDL_amigaevents_c.h"
  57. #include "SDL_cgxmodes_c.h"
  58. #include "SDL_cgximage_c.h"
  59. #include "SDL_cgxyuv_c.h"
  60. #include "SDL_cgxgl_c.h"
  61.  
  62. /* Initialization/Query functions */
  63. static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat);
  64. static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
  65. static int CGX_ToggleFullScreen(_THIS, int on);
  66. static void CGX_UpdateMouse(_THIS);
  67. static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
  68. static void CGX_VideoQuit(_THIS);
  69.  
  70. /* CGX driver bootstrap functions */
  71.  
  72. struct Library *CyberGfxBase=NULL;
  73. struct IntuitionBase *IntuitionBase=NULL;
  74. struct GfxBase *GfxBase=NULL;
  75.  
  76. static void DestroyScreen(_THIS)
  77. {
  78.       if(currently_fullscreen)
  79.     {
  80.         if(this->hidden->dbuffer)
  81.         {
  82.             extern struct MsgPort *safeport,*dispport;
  83.  
  84.             this->hidden->dbuffer=0;
  85.  
  86.             if(safeport)
  87.             {
  88.                 while(GetMsg(safeport)!=NULL);
  89.                 DeleteMsgPort(safeport);
  90.             }
  91.             if(dispport)
  92.             {
  93.                 while(GetMsg(dispport)!=NULL);
  94.                 DeleteMsgPort(dispport);
  95.             }
  96.  
  97.             this->hidden->SB[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=this->hidden->SB[0]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=NULL;
  98.             this->hidden->SB[1]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=this->hidden->SB[1]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=NULL;
  99.  
  100.             if(this->hidden->SB[1])
  101.                 FreeScreenBuffer(SDL_Display,this->hidden->SB[0]);
  102.             if(this->hidden->SB[0])
  103.                 FreeScreenBuffer(SDL_Display,this->hidden->SB[1]);
  104.  
  105.  
  106.             this->hidden->SB[0]=this->hidden->SB[1]=NULL;
  107.             free(SDL_RastPort);
  108.             SDL_RastPort=NULL;
  109.             this->hidden->dbuffer=0;
  110.         }
  111.         CloseScreen(GFX_Display);
  112.         currently_fullscreen=0;
  113.     }
  114.     else
  115.         UnlockPubScreen(NULL,GFX_Display);
  116.  
  117.     GFX_Display = NULL;
  118. }
  119.  
  120. static int CGX_Available(void)
  121. {
  122.     struct Library *l;
  123.  
  124.     l = OpenLibrary("cybergraphics.library",NULL);
  125.  
  126.     if ( l != NULL ) {
  127.         CloseLibrary(l);
  128.     }
  129.     return(l != NULL);
  130. }
  131.  
  132. static void CGX_DeleteDevice(SDL_VideoDevice *device)
  133. {
  134.     if ( device ) {
  135.         if ( device->hidden ) {
  136.             free(device->hidden);
  137.         }
  138.         if ( device->gl_data ) {
  139.             free(device->gl_data);
  140.         }
  141.         free(device);
  142.     }
  143. }
  144.  
  145. static SDL_VideoDevice *CGX_CreateDevice(int devindex)
  146. {
  147.     SDL_VideoDevice *device;
  148.  
  149.     /* Initialize all variables that we clean on shutdown */
  150.     device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
  151.     if ( device ) {
  152.         memset(device, 0, (sizeof *device));
  153.         device->hidden = (struct SDL_PrivateVideoData *)
  154.                 malloc((sizeof *device->hidden));
  155.         device->gl_data = (struct SDL_PrivateGLData *)
  156.                 malloc((sizeof *device->gl_data));
  157.     }
  158.     if ( (device == NULL) || (device->hidden == NULL) ||
  159.                              (device->gl_data == NULL) ) {
  160.         SDL_OutOfMemory();
  161.         CGX_DeleteDevice(device);
  162.         return(0);
  163.     }
  164.     memset(device->hidden, 0, (sizeof *device->hidden));
  165.     memset(device->gl_data, 0, (sizeof *device->gl_data));
  166.  
  167.     /* Set the driver flags */
  168.     device->handles_any_size = 1;
  169.  
  170.     /* Set the function pointers */
  171.     device->VideoInit = CGX_VideoInit;
  172.     device->ListModes = CGX_ListModes;
  173.     device->SetVideoMode = CGX_SetVideoMode;
  174.     device->ToggleFullScreen = CGX_ToggleFullScreen;
  175.     device->UpdateMouse = CGX_UpdateMouse;
  176. #ifdef XFREE86_XV
  177.     device->CreateYUVOverlay = X11_CreateYUVOverlay;
  178. #endif
  179.     device->SetColors = CGX_SetColors;
  180.     device->UpdateRects = NULL;
  181.     device->VideoQuit = CGX_VideoQuit;
  182.     device->AllocHWSurface = CGX_AllocHWSurface;
  183.     device->CheckHWBlit = CGX_CheckHWBlit;
  184.     device->FillHWRect = CGX_FillHWRect;
  185.     device->SetHWColorKey = CGX_SetHWColorKey;
  186.     device->SetHWAlpha = NULL;
  187.     device->LockHWSurface = CGX_LockHWSurface;
  188.     device->UnlockHWSurface = CGX_UnlockHWSurface;
  189.     device->FlipHWSurface = CGX_FlipHWSurface;
  190.     device->FreeHWSurface = CGX_FreeHWSurface;
  191. #ifdef HAVE_OPENGL
  192.     device->GL_LoadLibrary = X11_GL_LoadLibrary;
  193.     device->GL_GetProcAddress = X11_GL_GetProcAddress;
  194.     device->GL_GetAttribute = X11_GL_GetAttribute;
  195.     device->GL_MakeCurrent = X11_GL_MakeCurrent;
  196.     device->GL_SwapBuffers = X11_GL_SwapBuffers;
  197. #endif
  198.     device->SetIcon = CGX_SetIcon;
  199.     device->SetCaption = CGX_SetCaption;
  200.     device->IconifyWindow = NULL; /* CGX_IconifyWindow; */
  201.     device->GrabInput = NULL /* CGX_GrabInput*/; 
  202.     device->GetWMInfo = CGX_GetWMInfo;
  203.     device->FreeWMCursor = amiga_FreeWMCursor;
  204.     device->CreateWMCursor = amiga_CreateWMCursor;
  205.     device->ShowWMCursor = amiga_ShowWMCursor;
  206.     device->WarpWMCursor = amiga_WarpWMCursor;
  207.     device->CheckMouseMode = amiga_CheckMouseMode;
  208.     device->InitOSKeymap = amiga_InitOSKeymap;
  209.     device->PumpEvents = amiga_PumpEvents;
  210.  
  211.     device->free = CGX_DeleteDevice;
  212.  
  213.     return device;
  214. }
  215.  
  216. VideoBootStrap CGX_bootstrap = {
  217.     "CGX", "AmigaOS CyberGraphics", CGX_Available, CGX_CreateDevice
  218. };
  219.  
  220. #if 0
  221.  
  222. /* Create auxiliary (toplevel) windows with the current visual */
  223. static void create_aux_windows(_THIS)
  224. {
  225.     XSetWindowAttributes xattr;
  226.     XWMHints *hints;
  227.     XTextProperty titleprop, iconprop;
  228.     int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen));
  229.  
  230.     /* Don't create any extra windows if we are being managed */
  231.     if ( SDL_windowid ) {
  232.     FSwindow = 0;
  233.     WMwindow = strtol(SDL_windowid, NULL, 0);
  234.         return;
  235.     }
  236.  
  237.     if(FSwindow)
  238.     XDestroyWindow(SDL_Display, FSwindow);
  239.  
  240.     xattr.override_redirect = True;
  241.     xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0;
  242.     xattr.border_pixel = 0;
  243.     xattr.colormap = SDL_XColorMap;
  244.  
  245.     FSwindow = XCreateWindow(SDL_Display, SDL_Root, 0, 0, 32, 32, 0,
  246.                  this->hidden->depth, InputOutput, SDL_Visual,
  247.                  CWOverrideRedirect | CWBackPixel | CWBorderPixel
  248.                  | CWColormap,
  249.                  &xattr);
  250.  
  251.     XSelectInput(SDL_Display, FSwindow, StructureNotifyMask);
  252.  
  253.     /* Tell KDE to keep the fullscreen window on top */
  254.     {
  255.     XEvent ev;
  256.     long mask;
  257.  
  258.     memset(&ev, 0, sizeof(ev));
  259.     ev.xclient.type = ClientMessage;
  260.     ev.xclient.window = SDL_Root;
  261.     ev.xclient.message_type = XInternAtom(SDL_Display,
  262.                           "KWM_KEEP_ON_TOP", False);
  263.     ev.xclient.format = 32;
  264.     ev.xclient.data.l[0] = FSwindow;
  265.     ev.xclient.data.l[1] = CurrentTime;
  266.     mask = SubstructureRedirectMask;
  267.     XSendEvent(SDL_Display, SDL_Root, False, mask, &ev);
  268.     }
  269.  
  270.     hints = NULL;
  271.     titleprop.value = iconprop.value = NULL;
  272.     if(WMwindow) {
  273.     /* All window attributes must survive the recreation */
  274.     hints = XGetWMHints(SDL_Display, WMwindow);
  275.     XGetWMName(SDL_Display, WMwindow, &titleprop);
  276.     XGetWMIconName(SDL_Display, WMwindow, &iconprop);
  277.     XDestroyWindow(SDL_Display, WMwindow);
  278.     }
  279.  
  280.     /* Create the window for windowed management */
  281.     /* (reusing the xattr structure above) */
  282.     WMwindow = XCreateWindow(SDL_Display, SDL_Root, 0, 0, 32, 32, 0,
  283.                  this->hidden->depth, InputOutput, SDL_Visual,
  284.                  CWBackPixel | CWBorderPixel | CWColormap,
  285.                  &xattr);
  286.  
  287.     /* Set the input hints so we get keyboard input */
  288.     if(!hints) {
  289.     hints = XAllocWMHints();
  290.     hints->input = True;
  291.     hints->flags = InputHint;
  292.     }
  293.     XSetWMHints(SDL_Display, WMwindow, hints);
  294.     XFree(hints);
  295.     if(titleprop.value) {
  296.     XSetWMName(SDL_Display, WMwindow, &titleprop);
  297.     XFree(titleprop.value);
  298.     }
  299.     if(iconprop.value) {
  300.     XSetWMIconName(SDL_Display, WMwindow, &iconprop);
  301.     XFree(iconprop.value);
  302.     }
  303.  
  304.     XSelectInput(SDL_Display, WMwindow,
  305.          FocusChangeMask | KeyPressMask | KeyReleaseMask
  306.          | PropertyChangeMask | StructureNotifyMask);
  307.  
  308.     /* Set the class hints so we can get an icon (AfterStep) */
  309.     {
  310.     XClassHint *classhints;
  311.     classhints = XAllocClassHint();
  312.     if(classhints != NULL) {
  313.         classhints->res_name = "SDL_App";
  314.         classhints->res_class = "SDL_App";
  315.         XSetClassHint(SDL_Display, WMwindow, classhints);
  316.         XFree(classhints);
  317.     }
  318.     }
  319.  
  320.     /* Allow the window to be deleted by the window manager */
  321.     WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);
  322.     XSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1);
  323. }
  324. #endif
  325.  
  326. Uint32 MakeBitMask(_THIS,int type,int format,int *bpp)
  327. {
  328.     D(if(type==0)bug("REAL pixel format: "));
  329.  
  330.     if(this->hidden->depth==*bpp)
  331.     {
  332.         
  333.     switch(format)
  334.         {
  335.         case PIXFMT_LUT8:
  336.             D(if(type==0)bug("LUT8\n"));
  337.             return 0;
  338.         case PIXFMT_BGR15:
  339.         case PIXFMT_RGB15PC:
  340.             switch(type)
  341.             {
  342.                 case 0:
  343.                     D(bug("RGB15PC/BGR15\n"));
  344.                     return 31;
  345.                 case 1:
  346.                     return 992;
  347.                 case 2:
  348.                     return 31744;
  349.             }
  350.         case PIXFMT_RGB15:
  351.         case PIXFMT_BGR15PC:
  352.             switch(type)
  353.             {
  354.                 case 0:
  355.                     D(bug("RGB15/BGR15PC\n"));
  356.                     return 31744;
  357.                 case 1:
  358.                     return 992;
  359.                 case 2:
  360.                     return 31;
  361.             }
  362.         case PIXFMT_BGR16PC:
  363.         case PIXFMT_RGB16:
  364.             switch(type)
  365.             {
  366.                 case 0:
  367.                     D(bug("RGB16PC\n"));
  368.                     return 63488;
  369.                 case 1:
  370.                     return 2016;
  371.                 case 2:
  372.                     return 31;
  373.             }
  374.         case PIXFMT_BGR16:
  375.         case PIXFMT_RGB16PC:
  376.             switch(type)
  377.             {
  378.                 case 0:
  379.                     D(bug("RGB16PC/BGR16\n"));
  380.                     return 31;
  381.                 case 1:
  382.                     return 2016;
  383.                 case 2:
  384.                     return 63488;
  385.             }
  386.  
  387.         case PIXFMT_RGB24:
  388.             switch(type)
  389.             {
  390.                 case 0:
  391.                     D(bug("RGB24/BGR24\n"));
  392.                     return 0xff0000;
  393.                 case 1:
  394.                     return 0xff00;
  395.                 case 2:
  396.                     return 0xff;
  397.             }
  398.         case PIXFMT_BGR24:
  399.             switch(type)
  400.             {
  401.                 case 0:
  402.                     D(bug("BGR24\n"));
  403.                     return 0xff;
  404.                 case 1:
  405.                     return 0xff00;
  406.                 case 2:
  407.                     return 0xff0000;
  408.             }
  409.         case PIXFMT_ARGB32:
  410.             switch(type)
  411.             {
  412.                 case 0:
  413.                     D(bug("ARGB32\n"));
  414.                     return 0xff0000;
  415.                 case 1:
  416.                     return 0xff00;
  417.                 case 2:
  418.                     return 0xff;
  419.             }
  420.         case PIXFMT_BGRA32:
  421.             switch(type)
  422.             {
  423.                 case 0:
  424.                     D(bug("BGRA32\n"));
  425.                     return 0xff00;
  426.                 case 1:
  427.                     return 0xff0000;
  428.                 case 2:
  429.                     return 0xff000000;
  430.             }
  431.         case PIXFMT_RGBA32:
  432.             switch(type)
  433.             {
  434.                 case 0:
  435.                     D(bug("RGBA32\n"));
  436.                     return 0xff000000;
  437.                 case 1:
  438.                     return 0xff0000;
  439.                 case 2:
  440.                     return 0xff00;
  441.             }
  442.         default:
  443.             D(bug("Unknown pixel format! Default to 24bit\n"));
  444.             return (Uint32) (255<<(type*8));
  445.     }
  446.     }
  447.     else
  448.     {
  449.         D(if(type==0)bug("DIFFERENT from screen.\nAllocated screen format: "));
  450.     
  451.         switch(*bpp)
  452.         {
  453.             case 32:
  454.                 D(if(type==0) bug("RGBA32\n"));
  455.                 switch(type)
  456.                 {
  457.                     case 0:
  458.                         return 0xff000000;
  459.                     case 1:
  460.                         return 0xff0000;
  461.                     case 2:
  462.                         return 0xff00;
  463.                 }
  464.                 break;
  465.             case 24:
  466. use_truecolor:
  467.                 switch(type)
  468.                 {
  469.                     case 0:
  470.                         D(bug("RGB24\n"));
  471.                         return 0xff0000;
  472.                     case 1:
  473.                         return 0xff00;
  474.                     case 2:
  475.                         return 0xff;
  476.                 }
  477.             case 16:
  478.             case 15:
  479.                 D(if(type==0) bug("Not supported, switching to 24bit!\n"));
  480.                 *bpp=24;
  481.                 goto use_truecolor;
  482.                 break;                
  483.             default:
  484.                 D(if(type==0)bug("This is a chunky display\n"));
  485. // For chunky display mask is always 0;
  486.                 return 0;
  487.         }
  488.     } 
  489.     return 0;
  490. }
  491.  
  492. static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat)
  493. {
  494.     int i;
  495.  
  496.     if(!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39L)))
  497.     {
  498.         SDL_SetError("Couldn't open intuition V39+");
  499.         return -1;
  500.     }
  501.     if(!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39L)))
  502.     {
  503.         SDL_SetError("Couldn't open graphics V39+");
  504.         return -1;
  505.     }
  506.     if(!(CyberGfxBase=OpenLibrary("cybergraphics.library",40L)))
  507.     {
  508.         SDL_SetError("Couldn't open cybergraphics.");
  509.         return(-1);
  510.     }
  511.  
  512.     SDL_Display = LockPubScreen(NULL);
  513.  
  514.     if ( SDL_Display == NULL ) {
  515.         SDL_SetError("Couldn't lock the display");
  516.         return(-1);
  517.     }
  518.  
  519.     if(!IsCyberModeID(GetVPModeID(&SDL_Display->ViewPort)))
  520.     {
  521.         Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,SDL_Display->Width,
  522.                 CYBRBIDTG_NominalHeight,SDL_Display->Height,
  523.                 CYBRBIDTG_Depth,8,
  524.                 TAG_DONE);
  525.  
  526.         UnlockPubScreen(NULL,SDL_Display);
  527.  
  528.         GFX_Display=NULL;
  529.  
  530.         if(okid!=INVALID_ID)
  531.         {
  532.             GFX_Display=OpenScreenTags(NULL,
  533.                                     SA_Width,SDL_Display->Width,
  534.                                     SA_Height,SDL_Display->Height,
  535.                                     SA_Depth,8,SA_Quiet,TRUE,
  536.                                     SA_ShowTitle,FALSE,
  537.                                     SA_DisplayID,okid,
  538.                                     TAG_DONE);
  539.         }
  540.  
  541.         if(!GFX_Display)
  542.         {
  543.             SDL_SetError("Unable to open a suited CGX display");
  544.             return -1;
  545.         }
  546.         else SDL_Display=GFX_Display;
  547.  
  548.     }
  549.     else GFX_Display = SDL_Display;
  550.  
  551.  
  552.     /* See whether or not we need to swap pixels */
  553.  
  554.     swap_pixels = 0;
  555.  
  556. // Non e' detto che sia cosi' pero', alcune schede potrebbero gestire i modi in modo differente
  557.  
  558.     if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
  559.             swap_pixels = 1;
  560.     }
  561.  
  562.     /* Get the available video modes */
  563.     if(CGX_GetVideoModes(this) < 0)
  564.         return -1;
  565.  
  566.     /* Determine the default screen depth:
  567.        Use the default visual (or at least one with the same depth) */
  568.  
  569.     for(i = 0; i < this->hidden->nvisuals; i++)
  570.         if(this->hidden->visuals[i].depth == GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH))
  571.                     break;
  572.     if(i == this->hidden->nvisuals) {
  573.         /* default visual was useless, take the deepest one instead */
  574.         i = 0;
  575.     }
  576.     SDL_Visual = this->hidden->visuals[i].visual;
  577.  
  578. //    SDL_XColorMap = SDL_DisplayColormap;
  579.  
  580.     this->hidden->depth = this->hidden->visuals[i].depth;
  581.     D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
  582.     vformat->BitsPerPixel = this->hidden->visuals[i].depth; /* this->hidden->visuals[i].bpp; */
  583.  
  584.     {
  585.         int form;
  586.         APTR handle;
  587.         struct DisplayInfo info;
  588.  
  589.         if(!(handle=FindDisplayInfo(this->hidden->visuals[i].visual)))
  590.             return -1;
  591.  
  592.         if(!GetDisplayInfoData(handle,(char *)&info,sizeof(struct DisplayInfo),DTAG_DISP,NULL))
  593.             return -1;
  594.  
  595.         form=GetCyberIDAttr(CYBRIDATTR_PIXFMT,SDL_Visual);
  596.  
  597. // In this case I use makebitmask in a way that I'm sure I'll get PIXFMT pixel mask
  598.  
  599.         if ( vformat->BitsPerPixel > 8 ) 
  600.         {
  601.             vformat->Rmask = MakeBitMask(this,0,form,&this->hidden->depth);
  602.               vformat->Gmask = MakeBitMask(this,1,form,&this->hidden->depth);
  603.               vformat->Bmask = MakeBitMask(this,2,form,&this->hidden->depth);
  604.         }
  605.     }
  606.  
  607.     /* See if we have been passed a window to use */
  608. /*    SDL_windowid = getenv("SDL_WINDOWID"); */
  609.     SDL_windowid=NULL;
  610.  
  611.     /* Create the fullscreen and managed windows */
  612. //    create_aux_windows(this);
  613.  
  614.     /* Create the blank cursor */
  615.     SDL_BlankCursor = AllocMem(16,MEMF_CHIP|MEMF_CLEAR);
  616.  
  617.     /* Fill in some window manager capabilities */
  618.     this->info.wm_available = 1;
  619.     this->info.blit_hw = 1;
  620.     this->info.blit_hw_CC = 1;
  621.     this->info.blit_sw = 1;
  622.     this->info.blit_fill = 1;
  623.     this->info.video_mem=2000000; // Not always true but almost any Amiga card has this memory!
  624.  
  625.     this->hidden->same_format=0;
  626.     SDL_RastPort=&SDL_Display->RastPort;
  627.     /* We're done! */
  628.     return(0);
  629. }
  630.  
  631. void CGX_DestroyWindow(_THIS, SDL_Surface *screen)
  632. {
  633.     if ( ! SDL_windowid ) {
  634.         /* Hide the managed window */
  635.         int was_fullscreen=0;
  636.  
  637.         if ( screen && (screen->flags & SDL_FULLSCREEN) ) {    
  638.             was_fullscreen=1;
  639.             screen->flags &= ~SDL_FULLSCREEN;
  640. //            CGX_LeaveFullScreen(this); tolto x crash
  641.         }
  642.  
  643.         /* Destroy the output window */
  644.         if ( SDL_Window ) {
  645.             CloseWindow(SDL_Window);
  646.             SDL_Window=NULL;
  647.         }
  648.  
  649.         /* Free the colormap entries */
  650.         if ( SDL_XPixels ) {
  651.             int numcolors;
  652.             unsigned long pixel;
  653.  
  654.             if(this->screen->format&&this->hidden->depth==8&&!was_fullscreen)
  655.             {
  656.                 numcolors = 1<<this->screen->format->BitsPerPixel;
  657.  
  658.                 if(numcolors>256)
  659.                     numcolors=256;
  660.  
  661.                 if(!was_fullscreen&&this->hidden->depth==8)
  662.                 {
  663.                     for ( pixel=0; pixel<numcolors; pixel++ ) 
  664.                     {
  665.                         if(SDL_XPixels[pixel]>=0)
  666.                             ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]);
  667.                     }
  668.                 }
  669.             }
  670.             free(SDL_XPixels);
  671.             SDL_XPixels = NULL;
  672.         } 
  673.     }
  674. }
  675.  
  676. static void CGX_SetSizeHints(_THIS, int w, int h, Uint32 flags)
  677. {
  678.     if ( flags & SDL_RESIZABLE ) {
  679.         WindowLimits(SDL_Window, 32, 32,4096,4096);
  680.     } else {
  681.         WindowLimits(SDL_Window, w,h,w,h);
  682.     }
  683.     if ( flags & SDL_FULLSCREEN ) {
  684.         flags&=~SDL_RESIZABLE;
  685.     } else if ( getenv("SDL_VIDEO_CENTERED") ) {
  686.         int display_w, display_h;
  687.  
  688.         display_w = SDL_Display->Width;
  689.         display_h = SDL_Display->Height;
  690.         ChangeWindowBox(SDL_Window,(display_w - w - SDL_Window->BorderLeft-SDL_Window->BorderRight)/2,
  691.                     (display_h - h - SDL_Window->BorderTop-SDL_Window->BorderBottom)/2,
  692.                     w+SDL_Window->BorderLeft+SDL_Window->BorderRight,
  693.                     h+SDL_Window->BorderTop+SDL_Window->BorderBottom);
  694.     }
  695. }
  696.  
  697. int CGX_CreateWindow(_THIS, SDL_Surface *screen,
  698.                 int w, int h, int bpp, Uint32 flags)
  699. {
  700. #if 0
  701.     int i, depth;
  702.     Uint32 vis;
  703. #endif
  704.     /* If a window is already present, destroy it and start fresh */
  705.     if ( SDL_Window ) {
  706.         CGX_DestroyWindow(this, screen);
  707.     }
  708.  
  709.     /* See if we have been given a window id */
  710.     if ( SDL_windowid ) {
  711.         SDL_Window = (struct Window *)atol(SDL_windowid);
  712.     } else {
  713.         SDL_Window = 0;
  714.     }
  715.  
  716.     /* find out which visual we are going to use */
  717. #if 0
  718. /* questo l'ho spostato nell'apertura dello schermo, in quanto su Amiga le finestre
  719.    hanno il pixel mode degli schermi.
  720.  */
  721.     if ( flags & SDL_OPENGL ) {
  722.         SDL_SetError("OpenGL not supported by the Amiga SDL!");
  723.         return -1;
  724.     } 
  725.     else {
  726.         for ( i = 0; i < this->hidden->nvisuals; i++ ) {
  727.             if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */
  728.                 break;
  729.         }
  730.         if ( i == this->hidden->nvisuals ) {
  731.             SDL_SetError("No matching visual for requested depth");
  732.             return -1;    /* should never happen */
  733.         }
  734.         vis = this->hidden->visuals[i].visual;
  735.         depth = this->hidden->visuals[i].depth;
  736.     }
  737.     SDL_Visual = vis;
  738.     this->hidden->depth = depth;
  739.     D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
  740. #endif
  741.  
  742.     /* Allocate the new pixel format for this video mode */
  743.     {
  744.         Uint32 form;
  745.         APTR handle;
  746.         struct DisplayInfo info;
  747.  
  748.         if(!(handle=FindDisplayInfo(SDL_Visual)))
  749.             return -1;
  750.  
  751.         if(!GetDisplayInfoData(handle,(char *)&info,sizeof(struct DisplayInfo),DTAG_DISP,NULL))
  752.             return -1;
  753.  
  754.         form=GetCyberIDAttr(CYBRIDATTR_PIXFMT,SDL_Visual);
  755.  
  756.         if(flags&SDL_HWSURFACE)
  757.         {
  758.             if(bpp!=this->hidden->depth)
  759.             {
  760.                 bpp=this->hidden->depth;
  761.                 D(bug("Accel forces bpp to be equal (%ld)\n",bpp));
  762.             }
  763.         }
  764.  
  765.         D(bug("BEFORE screen allocation: bpp:%ld (real:%ld)\n",bpp,this->hidden->depth));
  766.  
  767. /* With this call if needed I'll revert the wanted bpp to a bpp best suited for the display, actually occurs
  768.    only with requested format 15/16bit and display format != 15/16bit
  769.  */    
  770.  
  771.         if ( ! SDL_ReallocFormat(screen, bpp,
  772.                 MakeBitMask(this,0,form,&bpp), MakeBitMask(this,1,form,&bpp), MakeBitMask(this,2,form,&bpp), 0) )
  773.             return -1;
  774.  
  775.         D(bug("AFTER screen allocation: bpp:%ld (real:%ld)\n",bpp,this->hidden->depth));
  776.  
  777.     }
  778.  
  779.     /* Create the appropriate colormap */
  780. /*
  781.     if ( SDL_XColorMap != SDL_DisplayColormap ) {
  782.         XFreeColormap(SDL_Display, SDL_XColorMap);
  783.     }
  784. */
  785.     if ( GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT)==PIXFMT_LUT8 || bpp==8 ) {
  786.         int ncolors;
  787.         D(bug("Alloco XPixels x la palette...\n"));
  788.  
  789.         /* Allocate the pixel flags */
  790.  
  791.         if(bpp==8)
  792.         ncolors=256;
  793.         else
  794.         ncolors = 1 << screen->format->BitsPerPixel;
  795.  
  796.         SDL_XPixels = (Sint32 *)malloc(ncolors * sizeof(Sint32));
  797.         
  798.         if(SDL_XPixels == NULL) {
  799.         SDL_OutOfMemory();
  800.         return -1;
  801.         }
  802.  
  803.         memset(SDL_XPixels, -1, ncolors * sizeof(Sint32));
  804.  
  805.         /* always allocate a private colormap on non-default visuals */
  806.         if(bpp==8)
  807.         flags |= SDL_HWPALETTE;
  808.  
  809.         if ( flags & SDL_HWPALETTE ) {
  810.             screen->flags |= SDL_HWPALETTE;
  811. /*
  812.             SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
  813.                                         SDL_Visual, AllocAll);
  814. */
  815.         } else {
  816. /*
  817.             SDL_XColorMap = SDL_DisplayColormap;
  818. */
  819.         }
  820.     } else {
  821. /*
  822.         SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
  823.                                         SDL_Visual, AllocNone);
  824. */
  825.     }
  826.  
  827.     /* Recreate the auxiliary windows, if needed (required for GL) */
  828. /*
  829.     if ( vis_change )
  830.         create_aux_windows(this);
  831. */
  832.  
  833.     /* resize the (possibly new) window manager window */
  834.  
  835.     /* Create (or use) the X11 display window */
  836.     if ( !SDL_windowid ) {
  837.         if ( flags & SDL_OPENGL ) {
  838.             return(-1);
  839.         } 
  840.         else 
  841.         {
  842.             if(flags & SDL_FULLSCREEN)
  843.             {
  844.                 SDL_Window = OpenWindowTags(NULL,WA_Width,w,WA_Height,h,
  845.                                             WA_Flags,WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_BORDERLESS|WFLG_BACKDROP|WFLG_REPORTMOUSE,
  846.                                             WA_IDCMP,IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE,
  847.                                             WA_CustomScreen,(ULONG)SDL_Display,
  848.                                             TAG_DONE);
  849.  
  850.                 D(bug("Apro finestra backdrop %ldx%ld su %lx!\n",w,h,SDL_Display));
  851.             }
  852.             else
  853.             {
  854.                 SDL_Window = OpenWindowTags(NULL,WA_InnerWidth,w,WA_InnerHeight,h,
  855.                                             WA_Flags,WFLG_REPORTMOUSE|WFLG_ACTIVATE|WFLG_RMBTRAP | ((flags&SDL_NOFRAME) ? 0 : (WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_DRAGBAR | ((flags&SDL_RESIZABLE) ? WFLG_SIZEGADGET|WFLG_SIZEBBOTTOM : 0))),
  856.                                             WA_IDCMP,IDCMP_RAWKEY|IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_NEWSIZE|IDCMP_MOUSEMOVE,
  857.                                             WA_PubScreen,(ULONG)SDL_Display,
  858.                                                         TAG_DONE);
  859.                 D(bug("Apro finestra %ldx%ld sul wb!\n",w,h));
  860.             }
  861.  
  862.         }
  863.         /* Only manage our input if we own the window */
  864. /*
  865.         XSelectInput(SDL_Display, SDL_Window,
  866.                     ( EnterWindowMask | LeaveWindowMask
  867.                     | ButtonPressMask | ButtonReleaseMask
  868.                     | PointerMotionMask | ExposureMask ));
  869. */
  870.  
  871.         if(!SDL_Window)
  872.             return -1;
  873.     }
  874.  
  875.     this->hidden->BytesPerPixel=GetCyberMapAttr(SDL_Window->RPort->BitMap,CYBRMATTR_BPPIX);
  876.  
  877.     if(screen->flags & SDL_DOUBLEBUF)
  878.     {
  879.         if(SDL_RastPort=malloc(sizeof(struct RastPort)))
  880.         {
  881.             InitRastPort(SDL_RastPort);
  882.             SDL_RastPort->BitMap=this->hidden->SB[1]->sb_BitMap;
  883.         }
  884.         else
  885.             return -1;
  886.     }
  887.     else SDL_RastPort=SDL_Window->RPort;
  888. #if 0
  889.  
  890.     if(screen->flags & SDL_HWPALETTE) {
  891.         /* Since the full-screen window might have got a nonzero background
  892.            colour (0 is white on some displays), we should reset the
  893.            background to 0 here since that is what the user expects
  894.            with a private colormap */
  895.         SetAPen(SDL_Window->RPort,0);
  896.         RectFill(SDL_Window->RPort,SDL_Window->BorderLeft,SDL_Window->BorderTop,w+SDL_Window->BorderLeft,h+SDL_Window->BorderTop);
  897.     }
  898. #endif
  899.  
  900.     if(flags&SDL_HWSURFACE)
  901.         screen->flags|=SDL_HWSURFACE;
  902.  
  903.     if( !SDL_windowid ) {
  904.         CGX_SetSizeHints(this, w, h, flags);
  905.         current_w = w;
  906.         current_h = h;
  907.     }
  908.  
  909.     /* Set our colormaps when not setting a GL mode */
  910. /*
  911.     if ( ! (flags & SDL_OPENGL) ) {
  912.         XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap);
  913.     }
  914. */
  915.  
  916.     /* Map them both and go fullscreen, if requested */
  917.     if ( ! SDL_windowid ) {
  918.         if ( flags & SDL_FULLSCREEN ) {
  919.             screen->flags |= SDL_FULLSCREEN;
  920.             currently_fullscreen=1;
  921. //            CGX_EnterFullScreen(this); Ci siamo gia'!
  922.         } else {
  923.             screen->flags &= ~SDL_FULLSCREEN;
  924.         }
  925.     }
  926.     screen->w = w;
  927.     screen->h = h;
  928.     screen->pitch = SDL_CalculatePitch(screen);
  929.     CGX_ResizeImage(this, screen, flags);
  930.  
  931.     return(0);
  932. }
  933.  
  934. int CGX_ResizeWindow(_THIS,
  935.             SDL_Surface *screen, int w, int h, Uint32 flags)
  936. {
  937.     if ( ! SDL_windowid ) {
  938.         /* Resize the window manager window */
  939.         CGX_SetSizeHints(this, w, h, flags);
  940.         current_w = w;
  941.         current_h = h;
  942.  
  943.         ChangeWindowBox(SDL_Window,SDL_Window->LeftEdge,SDL_Window->TopEdge, w+SDL_Window->BorderLeft+SDL_Window->BorderRight,
  944.                     h+SDL_Window->BorderTop+SDL_Window->BorderBottom);
  945.  
  946.         /* Resize the fullscreen and display windows */
  947. /*
  948.         if ( flags & SDL_FULLSCREEN ) {
  949.             if ( screen->flags & SDL_FULLSCREEN ) {
  950.                 CGX_ResizeFullScreen(this);
  951.             } else {
  952.                 screen->flags |= SDL_FULLSCREEN;
  953.                 CGX_EnterFullScreen(this);
  954.             }
  955.         } else {
  956.             if ( screen->flags & SDL_FULLSCREEN ) {
  957.                 screen->flags &= ~SDL_FULLSCREEN;
  958.                 CGX_LeaveFullScreen(this);
  959.             }
  960.         }
  961. */
  962.         screen->w = w;
  963.         screen->h = h;
  964.         screen->pitch = SDL_CalculatePitch(screen);
  965.         CGX_ResizeImage(this, screen, flags);
  966.     }
  967.     return(0);
  968. }
  969.  
  970. static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current,
  971.                 int width, int height, int bpp, Uint32 flags)
  972. {
  973.     Uint32 saved_flags;
  974.     int needcreate=0;
  975.  
  976.     /* Lock the event thread, in multi-threading environments */
  977.     SDL_Lock_EventThread();
  978.  
  979. // Check if the window needs to be closed or can be resized
  980.  
  981.     if( (flags&SDL_FULLSCREEN) || (current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN)))
  982.         needcreate=1;
  983.  
  984. // Check if we need to close an already existing videomode... 
  985.  
  986.     if(current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN))
  987.     {
  988.         unsigned long i;
  989.         CGX_DestroyImage(this,current);
  990.         CGX_DestroyWindow(this,current);
  991.         DestroyScreen(this);
  992.         D(bug("Distrutte immagine, finestra e schermo!\n"));
  993.         GFX_Display=SDL_Display=LockPubScreen(NULL);
  994.  
  995.         bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH);
  996.  
  997.         for ( i = 0; i < this->hidden->nvisuals; i++ ) {
  998.             if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */
  999.                 break;
  1000.         }
  1001.         if ( i == this->hidden->nvisuals ) {
  1002.             SDL_SetError("No matching visual for requested depth");
  1003.             return NULL;    /* should never happen */
  1004.         }
  1005.         SDL_Visual = this->hidden->visuals[i].visual;
  1006.  
  1007.         D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
  1008.         
  1009.     }
  1010.     /* Check the combination of flags we were passed */
  1011.     if ( flags & SDL_FULLSCREEN ) {
  1012.         int i;
  1013.     
  1014.         /* Clear fullscreen flag if not supported */
  1015.         if ( SDL_windowid ) {
  1016.             flags &= ~SDL_FULLSCREEN;
  1017.         }
  1018.         else if(current->flags&SDL_FULLSCREEN )
  1019.         {
  1020.             if(current->w!=width ||
  1021.                 current->h!=height ||
  1022.                 this->hidden->depth!=bpp)
  1023.             {
  1024.                 CGX_DestroyImage(this,current);
  1025.                 CGX_DestroyWindow(this,current);
  1026.                 DestroyScreen(this);
  1027.                 goto buildnewscreen;
  1028.             }
  1029.         }
  1030.         else
  1031. buildnewscreen:
  1032.         {
  1033.             Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,width,
  1034.                 CYBRBIDTG_NominalHeight,height,
  1035.                 CYBRBIDTG_Depth,bpp,
  1036.                 TAG_DONE);
  1037.  
  1038.             GFX_Display=NULL;
  1039.  
  1040.             if(okid!=INVALID_ID)
  1041.             {
  1042.                 GFX_Display=OpenScreenTags(NULL,
  1043.                                 SA_Width,width,
  1044.                                 SA_Height,height,
  1045.                                 SA_Quiet,TRUE,SA_ShowTitle,FALSE,
  1046.                                 SA_Depth,bpp,
  1047.                                 SA_DisplayID,okid,
  1048.                                 TAG_DONE);
  1049.             }
  1050.  
  1051.  
  1052.             if(!GFX_Display)
  1053.             {
  1054.                 GFX_Display=SDL_Display;
  1055.                 flags &= ~SDL_FULLSCREEN;
  1056.                 flags &= ~SDL_DOUBLEBUF;
  1057.             }
  1058.             else
  1059.             {
  1060.                 UnlockPubScreen(NULL,SDL_Display);
  1061.                 SDL_Display=GFX_Display;
  1062.  
  1063.                 if(flags&SDL_DOUBLEBUF)
  1064.                 {
  1065.                     int ok=0;
  1066.  
  1067.                     if(this->hidden->SB[0]=AllocScreenBuffer(SDL_Display,NULL,SB_SCREEN_BITMAP))
  1068.                     {
  1069.                         if(this->hidden->SB[1]=AllocScreenBuffer(SDL_Display,NULL,0L))
  1070.                         {
  1071.                             extern struct MsgPort *safeport,*dispport;
  1072.  
  1073.                             safeport=CreateMsgPort();
  1074.                             dispport=CreateMsgPort();
  1075.  
  1076.                             if(!safeport || !dispport)
  1077.                             {
  1078.                                 if(safeport)
  1079.                                 {
  1080.                                     DeleteMsgPort(safeport);
  1081.                                     safeport=NULL;
  1082.                                 }
  1083.                                 if(dispport)
  1084.                                 {
  1085.                                     DeleteMsgPort(dispport);
  1086.                                     dispport=NULL;
  1087.                                 }
  1088.                                 FreeScreenBuffer(SDL_Display,this->hidden->SB[0]);
  1089.                                 FreeScreenBuffer(SDL_Display,this->hidden->SB[1]);
  1090.                             }
  1091.                             else
  1092.                             {
  1093.                                 extern ULONG safe_sigbit,disp_sigbit;
  1094.                                 int i;
  1095.  
  1096.                                 safe_sigbit=1L<< safeport->mp_SigBit;
  1097.                                 disp_sigbit=1L<< dispport->mp_SigBit;
  1098.     
  1099.                                 for(i=0;i<2;i++)
  1100.                                 {
  1101.                                     this->hidden->SB[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=safeport;
  1102.                                     this->hidden->SB[i]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=dispport;
  1103.                                 }
  1104.  
  1105.                                 ok=1;
  1106.                                 D(bug("Dbuffering enabled!\n"));
  1107.                                 this->hidden->dbuffer=1;
  1108.                                 current->flags|=SDL_DOUBLEBUF;
  1109.                             }
  1110.                         }
  1111.                         else 
  1112.                         {
  1113.                             FreeScreenBuffer(SDL_Display,this->hidden->SB[1]);
  1114.                             this->hidden->SB[0]=NULL;
  1115.                         }
  1116.                     }
  1117.  
  1118.                     if(!ok)
  1119.                     {
  1120.                         flags&=~SDL_DOUBLEBUF;
  1121.                     }
  1122.                 }
  1123.             }
  1124.  
  1125.             if(GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH)==bpp)
  1126.                 this->hidden->same_format=1;                
  1127.         }
  1128.  
  1129.         bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH);
  1130.         D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
  1131.  
  1132.         for ( i = 0; i < this->hidden->nvisuals; i++ ) {
  1133.             if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */
  1134.                 break;
  1135.         }
  1136.         if ( i == this->hidden->nvisuals ) {
  1137.             SDL_SetError("No matching visual for requested depth");
  1138.             return NULL;    /* should never happen */
  1139.         }
  1140.         SDL_Visual = this->hidden->visuals[i].visual;
  1141.  
  1142.     }
  1143.  
  1144.     /* Set up the X11 window */
  1145.     saved_flags = current->flags;
  1146.  
  1147.     if (SDL_Window && (saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL)
  1148.         && bpp == current->format->BitsPerPixel && !needcreate) {
  1149.         if (CGX_ResizeWindow(this, current, width, height, flags) < 0) {
  1150.             current = NULL;
  1151.             goto done;
  1152.         }
  1153.     } else {
  1154.         if (CGX_CreateWindow(this,current,width,height,bpp,flags) < 0) {
  1155.             current = NULL;
  1156.             goto done;
  1157.         }
  1158.     }
  1159.  
  1160. #if 0
  1161.     /* Set up the new mode framebuffer */
  1162.     if ( ((current->w != width) || (current->h != height)) ||
  1163.              ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) {
  1164.         current->w = width;
  1165.         current->h = height;
  1166.         current->pitch = SDL_CalculatePitch(current);
  1167.         CGX_ResizeImage(this, current, flags);
  1168.     }
  1169. #endif
  1170.  
  1171.     current->flags |= (flags&SDL_RESIZABLE); // Resizable only if the user asked it
  1172.  
  1173.   done:
  1174.     /* Release the event thread */
  1175.     SDL_Unlock_EventThread();
  1176.  
  1177.     /* We're done! */
  1178.     return(current);
  1179. }
  1180.  
  1181. static int CGX_ToggleFullScreen(_THIS, int on)
  1182. {
  1183.     Uint32 event_thread;
  1184.  
  1185.     /* Don't switch if we don't own the window */
  1186.     if ( SDL_windowid ) {
  1187.         return(0);
  1188.     }
  1189.  
  1190.     /* Don't lock if we are the event thread */
  1191.     event_thread = SDL_EventThreadID();
  1192.     if ( event_thread && (SDL_ThreadID() == event_thread) ) {
  1193.         event_thread = 0;
  1194.     }
  1195.     if ( event_thread ) {
  1196.         SDL_Lock_EventThread();
  1197.     }
  1198.     if ( on ) {
  1199.         this->screen->flags |= SDL_FULLSCREEN;
  1200.         CGX_EnterFullScreen(this);
  1201.     } else {
  1202.         this->screen->flags &= ~SDL_FULLSCREEN;
  1203.         CGX_LeaveFullScreen(this);
  1204.     }
  1205.     CGX_RefreshDisplay(this);
  1206.     if ( event_thread ) {
  1207.         SDL_Unlock_EventThread();
  1208.     }
  1209.     SDL_ResetKeyboard();
  1210.     return(1);
  1211. }
  1212.  
  1213. static void SetSingleColor(Uint32 fmt, unsigned char r, unsigned char g, unsigned char b, unsigned char *c)
  1214. {
  1215.     switch(fmt)
  1216.     {
  1217.         case PIXFMT_BGR15:
  1218.         case PIXFMT_RGB15PC:
  1219.             {
  1220.                 Uint16 *t=(Uint16 *)c;
  1221.                 *t=(r>>3) | ((g>>3)<<5) | ((b>>3)<<10) ;
  1222.             }
  1223.             break;
  1224.         case PIXFMT_RGB15:
  1225.         case PIXFMT_BGR15PC:
  1226.             {
  1227.                 Uint16 *t=(Uint16 *)c;
  1228.                 *t=(b>>3) | ((g>>3)<<5) | ((r>>3)<<10) ;
  1229.             }
  1230.             break;
  1231.         case PIXFMT_BGR16PC:
  1232.         case PIXFMT_RGB16:
  1233.             {
  1234.                 Uint16 *t=(Uint16 *)c;
  1235.                 *t=(b>>3) | ((g>>2)<<5) | ((r>>3)<<11) ;
  1236.             }
  1237.             break;
  1238.         case PIXFMT_BGR16:
  1239.         case PIXFMT_RGB16PC:
  1240.             {
  1241.                 Uint16 *t=(Uint16 *)c;
  1242.                 *t=(r>>3) | ((g>>2)<<5) | ((b>>3)<<11) ;
  1243.             }
  1244.             break;
  1245.         case PIXFMT_RGB24:
  1246.             c[0]=r;
  1247.             c[1]=g;
  1248.             c[2]=b;
  1249.             c[3]=0;
  1250.             break;
  1251.         case PIXFMT_BGR24:
  1252.             c[0]=b;
  1253.             c[1]=g;
  1254.             c[2]=r;
  1255.             c[3]=0;
  1256.             break;
  1257.         case PIXFMT_ARGB32:
  1258.             c[0]=0;
  1259.             c[1]=r;
  1260.             c[2]=g;
  1261.             c[3]=b;
  1262.             break;
  1263.         case PIXFMT_BGRA32:
  1264.             c[0]=b;
  1265.             c[1]=g;
  1266.             c[2]=r;
  1267.             c[3]=0;
  1268.             break;
  1269.         case PIXFMT_RGBA32:
  1270.             c[0]=r;
  1271.             c[1]=g;
  1272.             c[2]=b;
  1273.             c[3]=0;
  1274.             break;
  1275.  
  1276.         default:
  1277.             D(bug("Errore, SetSingleColor con PIXFMT %ld!\n",fmt));
  1278.     }
  1279. }
  1280.  
  1281. /* Update the current mouse state and position */
  1282. static void CGX_UpdateMouse(_THIS)
  1283. {
  1284.     /* Lock the event thread, in multi-threading environments */
  1285.     SDL_Lock_EventThread();
  1286.  
  1287.     if(currently_fullscreen)
  1288.     {
  1289.             SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
  1290.             SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX, SDL_Display->MouseY);
  1291.     }
  1292.     else
  1293.     {
  1294.         if(    SDL_Display->MouseX>=(SDL_Window->LeftEdge+SDL_Window->BorderLeft) && SDL_Display->MouseX<(SDL_Window->LeftEdge+SDL_Window->Width-SDL_Window->BorderRight) &&
  1295.             SDL_Display->MouseY>=(SDL_Window->TopEdge+SDL_Window->BorderLeft) && SDL_Display->MouseY<(SDL_Window->TopEdge+SDL_Window->Height-SDL_Window->BorderBottom) 
  1296.             )
  1297.         {
  1298.             SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
  1299.             SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX-SDL_Window->LeftEdge-SDL_Window->BorderLeft, 
  1300.                                         SDL_Display->MouseY-SDL_Window->TopEdge-SDL_Window->BorderTop);
  1301.         }
  1302.         else
  1303.         {
  1304.             SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
  1305.         }
  1306.     }
  1307.     SDL_Unlock_EventThread();
  1308. }
  1309.  
  1310. static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
  1311. {
  1312.     int      i;
  1313.  
  1314.     /* Check to make sure we have a colormap allocated */
  1315.  
  1316.     /* It's easy if we have a hidden colormap */
  1317.     if ( (this->screen->flags & SDL_HWPALETTE) && currently_fullscreen ) 
  1318.     {
  1319.         ULONG  xcmap[256*3+2];
  1320.  
  1321.         xcmap[0]=(ncolors<<16);
  1322.         xcmap[0]+=firstcolor;
  1323.  
  1324. //        D(bug("Setting %ld colors on an HWPALETTE screen\n",ncolors));
  1325.  
  1326.         for ( i=0; i<ncolors; i++ ) {
  1327.             xcmap[i*3+1] = colors[i+firstcolor].r<<24;
  1328.             xcmap[i*3+2] = colors[i+firstcolor].g<<24;
  1329.             xcmap[i*3+3] = colors[i+firstcolor].b<<24;
  1330.         }
  1331.         xcmap[ncolors*3+1]=0;
  1332.         LoadRGB32(&GFX_Display->ViewPort,xcmap);
  1333.     } else {
  1334. // XPixels are not needed on 8bit screen with hwpalette
  1335.         unsigned long pixel;
  1336.  
  1337.         if ( SDL_XPixels == NULL ) {
  1338.             D(bug("SetColors without colormap!"));
  1339.             return(0);
  1340.         }
  1341.  
  1342.         if(this->hidden->depth==8)
  1343.         {
  1344. // In this case I have to unalloc and realloc the full palette
  1345.             D(bug("Obtaining %ld colors on the screen\n",ncolors));
  1346.     
  1347.         /* Free existing allocated colors */
  1348.             for ( pixel=0; pixel<this->screen->format->palette->ncolors; ++pixel ) {
  1349.                 if(SDL_XPixels[pixel]>=0)
  1350.                     ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]);
  1351.             }
  1352.  
  1353.         /* Try to allocate all the colors */
  1354.             for ( i=0; i<this->screen->format->palette->ncolors; ++i ) {
  1355.                 SDL_XPixels[i]=ObtainBestPenA(GFX_Display->ViewPort.ColorMap,colors[i].r<<24,colors[i].g<<24,colors[i].b<<24,NULL);
  1356.             }
  1357.         }
  1358.         else
  1359.         {            
  1360. #ifndef USE_CGX_WRITELUTPIXEL
  1361.             Uint32 fmt;
  1362.             D(bug("Preparing a conversion pixel table...\n"));
  1363.  
  1364.             fmt=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT);
  1365.  
  1366.             for(i=0;i<ncolors;i++)
  1367.             {
  1368.                 SetSingleColor(fmt,colors[firstcolor+i].r,colors[firstcolor+i].g,colors[firstcolor+i].b,(unsigned char *)&SDL_XPixels[firstcolor+i]);
  1369.             }
  1370. #else
  1371. //            D(bug("Eseguo remap degli XPixel(%lx): (da %ld, %ld colori) primo: r%ld g%ld b%ld\n",SDL_XPixels,firstcolor,ncolors,colors[firstcolor].r,colors[firstcolor].g,colors[firstcolor].b));
  1372.             for(i=0;i<ncolors;i++)
  1373.                 SDL_XPixels[i+firstcolor]=(colors[firstcolor+i].r<<16)+(colors[firstcolor+i].g<<8)+colors[firstcolor+i].b;
  1374. #endif
  1375.         }
  1376.     }
  1377.  
  1378. // Actually it cannot fail!
  1379.  
  1380.     return 1;
  1381. }
  1382.  
  1383. /* Note:  If we are terminated, this could be called in the middle of
  1384.    another SDL video routine -- notably UpdateRects.
  1385. */
  1386. static void CGX_VideoQuit(_THIS)
  1387. {
  1388.     /* Shutdown everything that's still up */
  1389.     /* The event thread should be done, so we can touch SDL_Display */
  1390.     if ( SDL_Display != NULL ) {
  1391.         /* Clean up OpenGL */
  1392.  
  1393.         /* Start shutting down the windows */
  1394.         CGX_DestroyImage(this, this->screen);
  1395.         CGX_DestroyWindow(this, this->screen);
  1396. // Otherwise SDL_VideoQuit will try to free it!
  1397.         SDL_VideoSurface=NULL;
  1398.         CGX_FreeVideoModes(this);
  1399.  
  1400. /*
  1401.         if ( SDL_iconcolors ) {
  1402.             unsigned long pixel;
  1403.             int numcolors =
  1404.                 ((this->screen->format)->palette)->ncolors;
  1405.             for ( pixel=0; pixel<numcolors; ++pixel ) {
  1406.                 while ( SDL_iconcolors[pixel] > 0 ) {
  1407.                     XFreeColors(SDL_Display,
  1408.                         SDL_DisplayColormap,&pixel,1,0);
  1409.                     --SDL_iconcolors[pixel];
  1410.                 }
  1411.             }
  1412.             free(SDL_iconcolors);
  1413.             SDL_iconcolors = NULL;
  1414.         } 
  1415. */
  1416.         /* Free that blank cursor */
  1417.         if ( SDL_BlankCursor != NULL ) {
  1418.             FreeMem(SDL_BlankCursor,16);
  1419.             SDL_BlankCursor = NULL;
  1420.         }
  1421.  
  1422.         /* Close the X11 graphics connection */
  1423.         this->hidden->same_format=0;
  1424.  
  1425.         if ( GFX_Display != NULL )
  1426.             DestroyScreen(this);
  1427.  
  1428.         /* Close the X11 display connection */
  1429.         SDL_Display = NULL;
  1430.  
  1431.         /* Unload GL library after X11 shuts down */
  1432.     }
  1433.  
  1434.     if( CyberGfxBase)
  1435.     {
  1436.         CloseLibrary(CyberGfxBase);
  1437.         CyberGfxBase=NULL;
  1438.     }
  1439.  
  1440.     if (IntuitionBase)
  1441.     {
  1442.         CloseLibrary((struct Library *)IntuitionBase);
  1443.         IntuitionBase=NULL;
  1444.     }
  1445.     if (GfxBase)
  1446.     {
  1447.         CloseLibrary((struct Library *)GfxBase);
  1448.         GfxBase=NULL;
  1449.     }
  1450.  
  1451.     if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) {
  1452.         /* Direct screen access, no memory buffer */
  1453.         this->screen->pixels = NULL;
  1454.     }
  1455. }
  1456.  
  1457.